//
// Created by Administrator on 2021/4/10.
//


/*给定一个二叉树，计算 整个树 的坡度 。

一个树的 节点的坡度 定义即为，该节点左子树的节点之和和右子树节点之和的 差的绝对值 。
如果没有左子树的话，左子树的节点之和为 0 ；没有右子树的话也是一样。空结点的坡度是 0 。

整个树 的坡度就是其所有节点的坡度之和。


输入：root = [1,2,3]
输出：1
解释：
节点 2 的坡度：|0-0| = 0（没有子节点）
节点 3 的坡度：|0-0| = 0（没有子节点）
节点 1 的坡度：|2-3| = 1（左子树就是左子节点，所以和是 2 ；右子树就是右子节点，所以和是 3 ）
坡度总和：0 + 0 + 1 = 1

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/binary-tree-tilt
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/binary-tree-tilt
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/

#include <iostream>

using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;

    explicit TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}

    TreeNode(int x, TreeNode *l, TreeNode *r) : val(x), left(l), right(r) {}
};

class Solution {
private :
    int tiltSum = 0;  // 整个树的坡度
public:
    int findTilt(TreeNode *root) {
        tilt(root);
        return tiltSum;
    }

    int tilt(TreeNode *root) {
        if (root == nullptr) return 0;
        int L = tilt(root->left);
        int R = tilt(root->right);
        tiltSum += abs(L - R);  // 更新坡度
        return L + R + root->val; // 返回该节点及子树之和
    }
};

int main() {
    auto t6 = TreeNode(7);
    auto t5 = TreeNode(5);
    auto t4 = TreeNode(3);
    auto t3 = TreeNode(9, nullptr, &t6);
    auto t2 = TreeNode(2, &t4, &t5);
    auto t1 = TreeNode(4, &t2, &t3);
    Solution sol;
    cout << sol.findTilt(&t1);
    return 0;
}